package 反射;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Ref;

public class ReflectUser {
    // 反射获取对象的四种方式
    // class.forName    object.getClass    ClassLoader.getSystemClassLoader().loadClass     类名.class
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException, InstantiationException {
        // 通过Clas.forName加载类
        Class<?> aClass = Class.forName("反射.User");
        User o = (User) aClass.newInstance();
        Method dance = aClass.getMethod("dance");
        // 拿到方法注解上面的参数
        Log annotation = dance.getAnnotation(Log.class);
        System.out.println(annotation.value());

//        User o = (User) aClass.newInstance();
//
//        o.dance();
//
//        //通过Java的对象获取Class对象
//        User user = new User("Tom");
//        Class<? extends User> aClass1 = user.getClass();
//        aClass1.getDeclaredMethod("dance").invoke(user);
//
//        //通过类名获取
//        Class<User> reflectUserClass = User.class;
//        Field name = reflectUserClass.getDeclaredField("name");
//        name.setAccessible(true);
//        User user2 = (User) reflectUserClass.newInstance();
//        name.set(user2, "Tom");
//        System.out.println(name.get(user2)); // 应该传入 user2 对象
//
//        // 通过ClassLoader类加载器实现类的加载
//        Class<?> aClass2 = ClassLoader.getSystemClassLoader().loadClass("反射.User");
//        User user3 = (User) aClass2.newInstance();
//        user3.dance();

//        User user = new User("Tom");
//        //Class.forName()通过反射拿到对象
//        //对象.getClassName()
//        Class<? extends User> clazz = user.getClass();
//
//        Field name = clazz.getDeclaredField("name");
//
//        //获取方法  如果方法有参数 那么还需要设置参数
//        Method getName = clazz.getMethod("getName");
//
//        System.out.println(getName.invoke(user));
//
//        //通过setAccessible方法，使得name字段可以被修改
//        name.setAccessible(true);
//
//        name.set(user, "Jerry");
//
//        System.out.println(user.getName());
    }
}
